//------------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
//            (C) COPYRIGHT 2008-2012 ARM Limited.
//                ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//------------------------------------------------------------------------------
// Version and Release Control Information:
//
// File Revision       : 127275
// File Date           :  2012-03-19 15:37:15 +0000 (Mon, 19 Mar 2012)
// Release Information : PL401-r0p1-00eac0
//------------------------------------------------------------------------------
// Purpose : This module contains the write pointer and FIFO storage
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
//        *** AUTOMATICALLY GENERATED, ONLY MODIFY MARKED SECTIONS ***
//
//  Config :
//           o  FIFO Depth  = 2
//
//
//------------------------------------------------------------------------------

`include "nic400_ib_chiplink_slv_axi4_tpv_ib_defs_ysyx_rv32.v"

  

// $async is: async

// FIFO logic in write clock domain


module nic400_ib_chiplink_slv_axi4_tpv_ib_b_fifo_wr_ysyx_rv32
  (
   // Outputs
   src_ready,
   dst_data,
   
   wpntr_gry_async,
   // Inputs
   wclk,
   wresetn,
   src_data,
   src_valid,
   rpntr_gry_async,
   rpntr_bin
   );

   // Write Clk, Reset and Sync Enable
   input        wclk;
   input        wresetn;

   // Write Clock Domain
   output                     src_ready;
   input  [5:0]               src_data;
   input                      src_valid;
   output [1:0]               wpntr_gry_async;

   // Read Clock Domain
   input [1:0]                rpntr_gry_async;
   input                      rpntr_bin;
   output [5:0]               dst_data;


    
  

   //------------------------------------------------------------------------
   // Registers
   //------------------------------------------------------------------------

   reg [1:0]      wpntr_gry;
  wire [1:0]      wpntr_gry_async;
   reg  [5:0]                 fifo0;
   wire [5:0]                 fifo0_corrupt;
   reg  [5:0]                 fifo1;
   wire [5:0]                 fifo1_corrupt;
  


   //------------------------------------------------------------------------
   // Wires
   //------------------------------------------------------------------------

   // next write pointers
   wire [1:0]  next_wpntr_gry;

   wire        wpntr_bin;
  // next write pointers
   wire [1:0]  rpntr_gry_wsync;


   wire [1:0]  wpntr_push;
     
   
   wire        full;
   wire        fifo_push;
   //------------------------------------------------------------------------
   // Functions
   //------------------------------------------------------------------------

`include "nic400_ib_chiplink_slv_axi4_tpv_ib_b_fifo_fn_ysyx_rv32.v"

   //------------------------------------------------------------------------
   // Main Code
   //------------------------------------------------------------------------

   assign src_ready = ~full;
   assign fifo_push = src_valid & ~full;

   
   // Synchronizer to bring the pointer into the clock domain (includes
   //   corrupt block)
   nic400_ib_chiplink_slv_axi4_tpv_ib_b_fifo_sync_ysyx_rv32 u_sync_rd_ptr_gry
   (
      .clk       (wclk),
      .resetn    (wresetn),
      .ptr_async (rpntr_gry_async),
      .ptr_sync  (rpntr_gry_wsync)
   );

   //Generate the write pointer to send cross domain
   nic400_cdc_launch_gry_ysyx_rv32 #(2) u_cdc_launch_wr_ptr_gry
   (
      .clk       (wclk),
      .resetn    (wresetn),
      .enable    (fifo_push),
      .in_cdc    (next_wpntr_gry),
      .out_async (wpntr_gry_async));
  

   // generate write pointer
   always@(posedge wclk or negedge wresetn)
     begin : p_wpnt_seq
        if(!wresetn)
           wpntr_gry <= {2{1'b0}};
        else if (fifo_push)
           wpntr_gry <= next_wpntr_gry;
     end

   // calculte next gray pointer
   assign next_wpntr_gry = nic400_ib_chiplink_slv_axi4_tpv_ib_b_fifo_next_gry_fn(wpntr_gry);

   // decode pointer to binary
   assign wpntr_bin      = nic400_ib_chiplink_slv_axi4_tpv_ib_b_fifo_gry_to_bin_fn(wpntr_gry);

   // data enables for each fifo entry
  
   assign wpntr_push[0] = fifo_push & (wpntr_bin       == 1'd0);
  
   assign wpntr_push[1] = fifo_push & (wpntr_bin       == 1'd1);
  
   // write data to fifo
      
   always@(posedge wclk)
    begin : p_wr_fifo0
      if(wpntr_push[0])
   fifo0 <= src_data;
    end
  
   always@(posedge wclk)
    begin : p_wr_fifo1
      if(wpntr_push[1])
   fifo1 <= src_data;
    end
  
  // CDC data corruption blocks. These blocks corrupt data for two dest cycles from any change
  
  //Corrupt fifo entry 0
  // payload width: 6
  nic400_ib_chiplink_slv_axi4_tpv_ib_cdc_air_corrupt_ysyx_rv32 #(6,"rev") u_cdc_corrupt_fifo_0
   (
      .d   (fifo0),
      .q   (fifo0_corrupt)
   );
  
  //Corrupt fifo entry 1
  // payload width: 6
  nic400_ib_chiplink_slv_axi4_tpv_ib_cdc_air_corrupt_ysyx_rv32 #(6,"rev") u_cdc_corrupt_fifo_1
   (
      .d   (fifo1),
      .q   (fifo1_corrupt)
   );
  

   // read data 
   nic400_ib_chiplink_slv_axi4_tpv_ib_b_fifo_wr_mux_ysyx_rv32 u_nic400_ib_chiplink_slv_axi4_tpv_ib_b_fifo_wr_mux
   (
      .in_0  (fifo0_corrupt),
      .in_1  (fifo1_corrupt),

      .sel   (rpntr_bin      ),
      .d_out (dst_data)
   );


  // check fifo is not full
   assign full = nic400_ib_chiplink_slv_axi4_tpv_ib_b_fifo_full_fn(wpntr_gry, rpntr_gry_wsync);
  

`ifdef ARM_ASSERT_ON
   //------------------------------------------------------------------------
   // OVL_ASSERT: Check that the pointers cannot exceed the fifo depth
   //------------------------------------------------------------------------

   // OVL_ASSERT_RTL
   assert_always #(0,0,"fifo pointer error")
   ovl_wr_pointer
     (
      .clk              (wclk),
      .reset_n          (wresetn),
      .test_expr        ((wpntr_bin       <= 1) && (rpntr_bin       <= 1))
     );
   // OVL_ASSERT_END

  `endif //  `ifdef ARM_ASSERT_ON

endmodule


`include "nic400_ib_chiplink_slv_axi4_tpv_ib_undefs_ysyx_rv32.v"

// --================================= End ===================================--
